package test;

import test.Tile.landType;
import test.Tile.objectType;

import java.util.*;

public class MapGen {
	private Random rndNum;
	private boolean lucky = false;
	private int MapWidth;
	private int MapHeight;
	private int NumStarts;
	private int NumIterations;
	private int seed;
	private Tile.landType mapArr[][];
	private Tile.objectType obArr [][];


	public MapGen(int W, int H,int seed)
	{
		MapWidth = W;
		MapHeight = H;
		this.seed = seed;
		mapArr = new Tile.landType[MapWidth][MapHeight];
		obArr = new Tile.objectType[MapWidth][MapHeight];
		System.out.println(seed);
		NumStarts = ((W*H)/(W+H)/2);
		NumIterations = (int)(((W*H)*.7)/NumStarts);
	}

	private boolean coord_valid(int x_in, int y_in)
	{
		if(y_in < 0 )
		{
			return false;
		}
		else if (y_in > MapHeight -1)
		{
			return false;
		}
		else if(x_in < 0)
		{
			return false;
		}
		else if (x_in > MapWidth -1)
		{
			return false;
		}
		return true;
	}

	public boolean checkUDRL(int x_in, int y_in, Tile.landType lt)
	{
		if(coord_valid(x_in, y_in))
		{
			if(coord_valid(x_in, y_in - 1) && mapArr[x_in][y_in-1] == lt)
				return true;
			if(coord_valid(x_in, y_in + 1) && mapArr[x_in][y_in+1] == lt) 
				return true;
			if(coord_valid(x_in - 1, y_in) && mapArr[x_in-1][y_in] == lt)
				return true;
			if(coord_valid(x_in + 1, y_in) && mapArr[x_in+1][y_in] == lt) 
				return true;
		}
		return false;

	}
	public boolean checkUDRL(int x_in, int y_in, Tile.objectType lt)
	{
		if(coord_valid(x_in, y_in))
		{
			if(coord_valid(x_in, y_in - 1) && obArr[x_in][y_in-1] == lt)
				return true;
			if(coord_valid(x_in, y_in + 1) && obArr[x_in][y_in+1] == lt) 
				return true;
			if(coord_valid(x_in - 1, y_in) && obArr[x_in-1][y_in] == lt)
				return true;
			if(coord_valid(x_in + 1, y_in) && obArr[x_in+1][y_in] == lt) 
				return true;
		}
		return false;

	}
	public boolean checkAllAround(int x_in, int y_in, Tile.landType lt )
	{
		if(checkUDRL(x_in,y_in, lt))
			return true;
		else 
		{
			if(coord_valid(x_in-1, y_in-1) && mapArr[x_in-1][y_in-1] == lt)
			{
				return true;
			}
			if(coord_valid(x_in+1, y_in-1) && mapArr[x_in+1][y_in-1] == lt)
			{
				return true;
			}
			if(coord_valid(x_in-1, y_in+1) && mapArr[x_in-1][y_in+1] == lt)
			{
				return true;
			}
			if(coord_valid(x_in+1, y_in+1) && mapArr[x_in+1][y_in+1] == lt)
			{
				return true;
			}
		}
		return false;
	}
	public boolean checkAllAround(int x_in, int y_in, Tile.objectType lt )
	{
		if(checkUDRL(x_in,y_in, lt))
			return true;
		else 
		{
			if(coord_valid(x_in-1, y_in-1) && obArr[x_in-1][y_in-1] == lt)
			{
				return true;
			}
			if(coord_valid(x_in+1, y_in-1) && obArr[x_in+1][y_in-1] == lt)
			{
				return true;
			}
			if(coord_valid(x_in-1, y_in+1) && obArr[x_in-1][y_in+1] == lt)
			{
				return true;
			}
			if(coord_valid(x_in+1, y_in+1) && obArr[x_in+1][y_in+1] == lt)
			{
				return true;
			}
		}
		return false;
	}
	private void generateLandTiles(int x_start, int x_end, int y_start, int y_end, int starts, int iterations, landType startType, landType endType)
	{
		int count = 0;
		int x=0, y=0;
		int coordArr[][] = new int[starts][2];//keep track of starting coordinates
		while(count < starts)
		{
			x = rndNum.nextInt(x_end - x_start) + x_start;
			y = rndNum.nextInt(y_end - y_start) + y_start;
			if(mapArr[x][y] == startType)
			{
				mapArr[x][y] = endType;
				coordArr[count][0] = x;
				coordArr[count][1] = y;
				count++;
			}
		}

		int origLoc[][] = new int[starts][2];//keep track of original coordinates
		for(int v = 0; v < starts; v++)
			for(int g = 0; g < 2; g++)
				origLoc[v][g] = coordArr[v][g];
		for(int j = 0; j < iterations; j++)
		{
			for(int i=0; i<starts;i++)
			{
				if(checkUDRL(coordArr[i][0],coordArr[i][1],startType))
				{
					//pick random tile around this one
					int nX = 0;
					int nY = 0;
					boolean done = false;
					while(!done)//pick the next one
					{
						int XorY = rndNum.nextInt(2);
						if(XorY == 0)
						{
							nX = (rndNum.nextInt(2) * 2) -1;//-1, 0, 1 
						}
						else if(XorY == 1)
						{
							//		std::cout << "after";//testing///////////////////////
							nY = (rndNum.nextInt(2) * 2) -1;//-1, 0, 1 
						}
						if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
								mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
							done = true;
						else
						{
							/*int first = rndNum.nextInt(2);
							if(first == 0)
							{
								nX = (nX == 0 ? 1 : 0);
								if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
									mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
									done = true;
								else
								{
									nX = (nX == 0 ? 1 : 0);
									nY = (nY == 0 ? 1 : 0);
									//done = true;
								}
							}
							else
							{
								nY = (nY == 0 ? 1 : 0);
								if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
									mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
									done = true;
								else
								{
									nY = (nY == 0 ? 1 : 0);
									nX = (nX == 0 ? 1 : 0);
									//done = true;
								}
							}*/
							if(nX == 0)
							{
								nY *= -1;
								if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
										mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
									break;
								nX = 1;
								if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
										mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
									break;
								nY = -1;
								if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
										mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
									break;
								nY = 0;
								if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
										mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
									break;
								nY = 1;
								if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
										mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
									break;
								nX = -1;
								if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
										mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
									break;
								nY = -1;
								if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
										mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
									break;
								nY = 0;
								if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
										mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
									break;
							}
							else
							{
								nX *= -1;
								if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
										mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
									break;
								nY = 1;
								if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
										mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
									break;
								nX = -1;
								if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
										mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
									break;
								nX = 0;
								if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
										mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
									break;
								nX = 1;
								if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
										mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
									break;
								nY = -1;
								if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
										mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
									break;
								nX = -1;
								if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
										mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
									break;
								nX = 0;
								if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
										mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
									break;
							}
						}
					}
					mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] = endType;
				}
				else
				{
					while(!checkUDRL(coordArr[i][0],coordArr[i][1],startType))
					{
						//replace current coordArr[i] with random adjacent tile into
						int nX = 0;
						int nY = 0;
						boolean done = false;
						while(!done)//pick the next one
						{
							int XorY = rndNum.nextInt(2);
							nX = 0;
							nY = 0;
							if(XorY == 0)
							{
								nX = (rndNum.nextInt(2) * 2) -1;//-1, 1 
							}
							else if(XorY == 1)
							{
								//		std::cout << "after";//testing///////////////////////
								nY = (rndNum.nextInt(2) * 2) -1;//-1, 1 
							}
							//check for valid coordinates 
							if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY))
							{
								done = true;
							}
						}
						if(coord_valid(coordArr[i][0] + 1, coordArr[i][0]) &&
								coord_valid(coordArr[i][0] - 1, coordArr[i][0]) &&
								coord_valid(coordArr[i][0], coordArr[i][0] + 1) &&
								coord_valid(coordArr[i][0], coordArr[i][0] - 1))
						{	//ARE YOU ON THE EDGE?... THE EDGE OF AWESOME!!!!!
							coordArr[i][0] = coordArr[i][0] + nX;
							coordArr[i][1] = coordArr[i][1] + nY;
						}
						else
						{
							coordArr[i][0] = origLoc[i][0];
							coordArr[i][1] = origLoc[i][1];
						}
					}
					
					//After the coordArr coordinate is next to water, run the code to make a land tile
					int nX = 0;
					int nY = 0;
					boolean done = false;
					while(!done)//pick the next one
					{
						int XorY = rndNum.nextInt(2);
						if(XorY == 0)
						{
							nX = (rndNum.nextInt(2) * 2) -1;//-1, 0, 1 
						}
						else if(XorY == 1)
						{
							//		std::cout << "after";//testing///////////////////////
							nY = (rndNum.nextInt(2) * 2) -1;//-1, 0, 1 
						}
						if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY))
						{
							done = true;
						}
					}
					mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] = endType;
				}
			}
		}
	}
	private void generateTrees(int width, int height, int starts, int iterations, landType startType, objectType putType)
	{
		int count = 0;
		int x=0, y=0;
		int coordArr[][] = new int[starts][2];//keep track of starting coordinates
		while(count < starts)
		{
			x = rndNum.nextInt(width);
			y = rndNum.nextInt(height);
			if(mapArr[x][y] == startType)
			{
				obArr[x][y] = putType;
				coordArr[count][0] = x;
				coordArr[count][1] = y;
				count++;
			}
		}

		int origLoc[][] = new int[starts][2];//keep track of original coordinates
		for(int v = 0; v < starts; v++)
			for(int g = 0; g < 2; g++)
				origLoc[v][g] = coordArr[v][g];
		for(int j = 0; j < iterations; j++)
		{
			for(int i=0; i<starts;i++)
			{
				if(checkUDRL(coordArr[i][0],coordArr[i][1],putType) && checkUDRL(coordArr[i][0],coordArr[i][1],startType))
				{
					//pick random tile around this one
					int nX = 0;
					int nY = 0;
					boolean done = false;
					while(!done)//pick the next one
					{
						//System.out.println(done);
						int XorY = rndNum.nextInt(2);
						if(XorY == 0)
						{
							nX = (rndNum.nextInt(2) * 2) -1;//-1, 0, 1 
						}
						else if(XorY == 1)
						{
							//		std::cout << "after";//testing///////////////////////
							nY = (rndNum.nextInt(2) * 2) -1;//-1, 0, 1 
						}
						if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
								//obArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == objectType.AIR &&
								mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
							done = true;
						else
						{
							/*int first = rndNum.nextInt(2);
							if(first == 0)
							{
								nX = (nX == 0 ? 1 : 0);
								if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
									//obArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == objectType.AIR &&
									mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
									done = true;
								else
								{
									nX = (nX == 0 ? 1 : 0);
									nY = (nY == 0 ? 1 : 0);
									done = true;
								}
							}
							else
							{
								nY = (nY == 0 ? 1 : 0);
								if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
									//obArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == objectType.AIR &&
									mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
									done = true;
								else
								{
									nY = (nY == 0 ? 1 : 0);
									nX = (nX == 0 ? 1 : 0);
									done = true;
								}
							}*/
							if(nX == 0)
							{
								nY *= -1;
								if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
										obArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == objectType.AIR &&
										mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
									break;
								nX = 1;
								if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
										obArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == objectType.AIR &&
										mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
									break;
								nY = -1;
								if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
										obArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == objectType.AIR &&
										mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
									break;
								nY = 0;
								if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
										obArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == objectType.AIR &&
										mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
									break;
								nY = 1;
								if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
										obArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == objectType.AIR &&
										mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
									break;
								nX = -1;
								if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
										obArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == objectType.AIR &&
										mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
									break;
								nY = -1;
								if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
										obArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == objectType.AIR &&
										mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
									break;
								nY = 0;
								if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
										obArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == objectType.AIR &&
										mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
									break;
							}
							else
							{
								nX *= -1;
								if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
										obArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == objectType.AIR &&
										mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
									break;
								nY = 1;
								if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
										obArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == objectType.AIR &&
										mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
									break;
								nX = -1;
								if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
										obArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == objectType.AIR &&
										mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
									break;
								nX = 0;
								if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
										obArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == objectType.AIR &&
										mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
									break;
								nX = 1;
								if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
										obArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == objectType.AIR &&
										mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
									break;
								nY = -1;
								if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
										obArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == objectType.AIR &&
										mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
									break;
								nX = -1;
								if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
										obArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == objectType.AIR &&
										mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
									break;
								nX = 0;
								if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY) &&
										obArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == objectType.AIR &&
										mapArr[coordArr[i][0] + nX][coordArr[i][1] + nY] == startType)
									break;
							}
						}
						
					}
					obArr[coordArr[i][0] + nX][coordArr[i][1] + nY] = putType;
				}
				else
				{
					System.out.println("got here");
					while(!checkUDRL(coordArr[i][0],coordArr[i][1],putType) && !checkUDRL(coordArr[i][0],coordArr[i][1],startType))
					{
						//replace current coordArr[i] with random adjacent tile into
						int nX = 0;
						int nY = 0;
						boolean done = false;
						while(!done)//pick the next one
						{
							int XorY = rndNum.nextInt(2);
							nX = 0;
							nY = 0;
							if(XorY == 0)
							{
								nX = (rndNum.nextInt(2) * 2) -1;//-1, 1 
							}
							else if(XorY == 1)
							{
								//		std::cout << "after";//testing///////////////////////
								nY = (rndNum.nextInt(2) * 2) -1;//-1, 1 
							}
							//check for valid coordinates 
							if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY))
							{
								done = true;
							}
						}
						if(coord_valid(coordArr[i][0] + 1, coordArr[i][0]) &&
								coord_valid(coordArr[i][0] - 1, coordArr[i][0]) &&
								coord_valid(coordArr[i][0], coordArr[i][0] + 1) &&
								coord_valid(coordArr[i][0], coordArr[i][0] - 1))
						{	//ARE YOU ON THE EDGE?... THE EDGE OF AWESOME!!!!!
							coordArr[i][0] = coordArr[i][0] + nX;
							coordArr[i][1] = coordArr[i][1] + nY;
						}
						else
						{
							coordArr[i][0] = origLoc[i][0];
							coordArr[i][1] = origLoc[i][1];
						}
					}
					
					//After the coordArr coordinate is next to water, run the code to make a land tile
					int nX = 0;
					int nY = 0;
					boolean done = false;
					while(!done)//pick the next one
					{
						int XorY = rndNum.nextInt(2);
						if(XorY == 0)
						{
							nX = (rndNum.nextInt(2) * 2) -1;//-1, 0, 1 
						}
						else if(XorY == 1)
						{
							//		std::cout << "after";//testing///////////////////////
							nY = (rndNum.nextInt(2) * 2) -1;//-1, 0, 1 
						}
						if(coord_valid(coordArr[i][0] + nX, coordArr[i][1] + nY))
						{
							done = true;
						}
					}
					obArr[coordArr[i][0] + nX][coordArr[i][1] + nY] = putType;
				}
			}
		}
	}
	
	public void generate(){
		// set seed
		rndNum = new Random(seed);
		//init all map to water
		for(int i=0; i<MapWidth; i++){
			for(int j=0; j<MapHeight;j++){
				mapArr[i][j] = landType.WATER;
			}
		}
		//if you are lucky it will be lava
		int luckyNum = rndNum.nextInt(1337);
		if(luckyNum % 1337 == 0) lucky = true;
		if(lucky)
		{
			for(int i=0; i<MapWidth; i++){
				for(int j=0; j<MapHeight;j++){
					mapArr[i][j] = landType.LAVA;//he he
				}
			}
		}
		//init all objects to air
		for(int i=0; i<MapWidth; i++){
			for(int j=0; j<MapHeight;j++){
				obArr[i][j] = objectType.AIR;
			}
		}
		//pick places for starting tiles of land
		if(!lucky)
			generateLandTiles(MapWidth/3, (MapWidth*2)/3, MapHeight/3, (MapHeight*2)/3, NumStarts, NumIterations, landType.WATER, landType.GRASS);
		else
			generateLandTiles(MapWidth/3, (MapWidth*2)/3, MapHeight/3, (MapHeight*2)/3, NumStarts, NumIterations, landType.LAVA, landType.GRASS);

		
		//turn edges of map to water
		for(int i=0; i<4; i++)//top
		{
			for(int j=0; j<MapHeight;j++){
				if(!lucky)
					mapArr[i][j] = landType.WATER;
				else
					mapArr[i][j] = landType.LAVA;
			}
		}
		for(int i=MapWidth-4; i<MapWidth; i++)//bottom
		{
			for(int j=0; j<MapWidth;j++){
				if(!lucky)
					mapArr[i][j] = landType.WATER;
				else
					mapArr[i][j] = landType.LAVA;
			}
		}
		for(int i=0; i<MapWidth; i++)//left
		{
			for(int j=0; j<4;j++){
				if(!lucky)
					mapArr[i][j] = landType.WATER;
				else
					mapArr[i][j] = landType.LAVA;
			}
		}
		for(int i=0; i<MapWidth; i++)//right
		{
			for(int j=MapHeight-4; j<MapHeight;j++){
				if(!lucky)
					mapArr[i][j] = landType.WATER;
				else
					mapArr[i][j] = landType.LAVA;
			}
		}
		//one square of water is a swamp
		for(int i=0; i<MapWidth; i++)
		{
			for(int j=0; j<MapHeight;j++){
				if(mapArr[i][j] == landType.WATER && !checkUDRL(i, j, landType.WATER))
				{
					mapArr[i][j] = landType.GENTYPE;
				}
			}
		}
		for(int i=0; i<MapWidth; i++)
		{
			for(int j=0; j<MapHeight;j++){
				if(checkAllAround(i,j,landType.GENTYPE))
				{
					mapArr[i][j] = landType.SWAMP;
				}
			}
		}
		//swamp it again
		for(int i=0; i<MapWidth; i++)
		{
			for(int j=0; j<MapHeight;j++){
				if(mapArr[i][j] == landType.GRASS && checkUDRL(i, j, landType.SWAMP))
				{
					mapArr[i][j] = landType.GENTYPE;
				}
			}
		}
		for(int i=0; i<MapWidth; i++)
		{
			for(int j=0; j<MapHeight;j++){
				if(mapArr[i][j] == landType.GENTYPE)
				{
					mapArr[i][j] = landType.SWAMP;
				}
			}
		}
		
		// Turn Grass next to water into sand
		for(int i=0; i<MapWidth; i++)
		{
			for(int j=0; j<MapHeight;j++){
				if(mapArr[i][j] == landType.GRASS && checkAllAround(i, j, landType.WATER))
				{
					mapArr[i][j] = landType.SAND;
				}
				if(lucky && mapArr[i][j] == landType.GRASS && checkAllAround(i, j, landType.LAVA))
				{
					mapArr[i][j] = landType.DIRT;
				}
			}
		}
		for(int i=0; i<MapWidth; i++)
		{
			for(int j=0; j<MapHeight;j++){
				if(mapArr[i][j] == landType.GENTYPE)
				{
					mapArr[i][j] = landType.WATER;
				}
			}
		}
		// Then do it again, they never expect....
				for(int i=0; i<MapWidth; i++)
				{
					for(int j=0; j<MapHeight;j++){
						if(mapArr[i][j] == landType.GRASS && checkAllAround(i, j, landType.SAND))
						{
							mapArr[i][j] = landType.GENTYPE;
						}
					}
				}
				for(int i=0; i<MapWidth; i++)
				{
					for(int j=0; j<MapHeight;j++){
						if(mapArr[i][j] == landType.GENTYPE)
						{
							mapArr[i][j] = landType.SAND;
						}
					}
				}
		//to-do place trees
		//generateTrees(MapWidth, MapHeight, 3, 50, landType.GRASS, objectType.TREE);
		int treeStarts = (int) ((MapWidth*MapHeight)/(MapWidth+MapHeight)/2);
		int numTrees =(int) ((MapWidth*MapHeight)/(MapWidth+MapHeight))*4;
		int x, y;
		for(int i=0; i<treeStarts;)
		{
			x = rndNum.nextInt(MapWidth);
			y = rndNum.nextInt(MapHeight);
			if(mapArr[x][y] == landType.GRASS && obArr[x][y] == objectType.AIR)
			{
				obArr[x][y] = objectType.TREE;
				i++;
			}
		}
		for(int i=0; i<numTrees;)
		{
			x = rndNum.nextInt(MapWidth);
			y = rndNum.nextInt(MapHeight);
			int num = 0;
			if(mapArr[x][y] == landType.GRASS && obArr[x][y] == objectType.AIR)
			{
				if(checkUDRL(x, y, objectType.TREE))
				{
					obArr[x][y] = objectType.TREE;
					i++;
				}
				else
				{
					num = rndNum.nextInt(3);
					if(num % 3==0)
					{
						obArr[x][y] = objectType.TREE;
						i++;
					}
				}
			}
		}
		//to-do place rocks
		int numRocks =(int) ((MapWidth*MapHeight)/(MapWidth+MapHeight));
		for(int i=0; i<numRocks;)
		{
			x = rndNum.nextInt(MapWidth);
			y = rndNum.nextInt(MapHeight);
			int num = 0;
			if(mapArr[x][y] == landType.GRASS && obArr[x][y] == objectType.AIR)
			{
				if(checkAllAround(x, y, objectType.ROCK))
				{
					obArr[x][y] = objectType.ROCK;
					i++;
				}
				else
				{
					num = rndNum.nextInt(3);
					if(num % 3==0)
					{
						obArr[x][y] = objectType.ROCK;
						i++;
					}
				}
			}
		}
		//Make it dirty
		for(int i=0; i<numTrees;)
		{
			x = rndNum.nextInt(MapWidth);
			y = rndNum.nextInt(MapHeight);
			int num = 0;
			if(mapArr[x][y] == landType.GRASS)
			{
				if(checkUDRL(x, y, landType.DIRT))
				{
					mapArr[x][y] = landType.DIRT;
					i++;
				}
				else
				{
					num = rndNum.nextInt(7);
					if(num % 7==0)
					{
						mapArr[x][y] = landType.DIRT;
						i++;
					}
				}
			}
		}
	}
	
	public void print(){
		char workChar = ' ';
		for(int i=0; i<MapWidth; i++){
			for(int j=0; j<MapHeight;j++){
				switch(mapArr[i][j].ordinal())
				{
				case 0: 
					workChar = '.';
					break;
				case 1:
					workChar = 'L';
					break;
				case 2:
					workChar = '#';
					break;
				case 3:
					workChar = 'G';
					break;
				case 4:
					workChar = 'S';
					break;
				case 5:
					workChar = 'W';
					break;
				default:
					workChar = 'E';
				}
				switch(obArr[i][j].ordinal())
				{
				case 0:
					break;
				case 1: 
					workChar = 'T';
					break;
				case 2:
					workChar = 'R';
					break;
				default:
					workChar = 'e';
				}
				System.out.print(workChar + " ");
				//System.out.print((mapArr[i][j].ordinal() == 1 ? "." :(c ? t :"#")) + " ");
			}
			System.out.println();
		}
	}
	 public WorldMap toMapObject()
	  {
	    WorldMap wm = new WorldMap(MapWidth, MapHeight);
	    for(int i = 0; i < MapWidth; i++)
	    {
	      for(int j = 0; j < MapHeight; j++)
	      {
	        int style = rndNum.nextInt(2);
	        switch(mapArr[j][i])
	        {
	          case landType.WATER:
	            if(style == 0)
	              wm.setTile(i, Cowquisition.water1);
	            else
	              wm.setTile(i, Cowquisition.water2);
	            break;
	          case landType.LAVA:
	            if(style == 0)
	              wm.setTile(i, Cowquisition.lava1);
	            else
	              wm.setTile(i, Cowquisition.lava2);
	            break;
	          case landType.GRASS:
	            if(style == 0)
	              wm.setTile(i, Cowquisition.grass1);
	            else
	              wm.setTile(i, Cowquisition.grass2);
	            break;
	          case landType.DIRT:
	            if(style == 0)
	              wm.setTile(i, Cowquisition.dirt1);
	            else
	              wm.setTile(i, Cowquisition.dirt2);
	            break;
	          case landType.SWAMP:
	            if(style == 0)
	              wm.setTile(i, Cowquisition.swamp1);
	            else
	              wm.setTile(i, Cowquisition.swamp2);
	            break;
	          case landType.SAND:
	            if(style == 0)
	              wm.setTile(i, Cowquisition.sand1);
	            else
	              wm.setTile(i, Cowquisition.sand2);
	            break;
	        }
	      }
	    }
	    return wm;
	  }
}

/* 
 * 50x50 seed 9001<br>
 * Find The Elephant!!!<br>
 * . . . . . . . . . . . . # # # . . . . # # # # . . . . . . . . . . . . . . . . . . . . . . . . . . . <br>
 * . . . . . # # # # # # # # # # . # # # # # # # # # . . . . . . . . . . . . . . . . . . . . . . . . . <br>
 * . . . . # # # # # # # # # # # # # # # # # # # # # . . . . . . . . . . . . . . . . . . . . . . . . . <br>
 * . . . . . # # # # # # # # # # # # # # # # # # # # . . . . . . . . . . . . . . . . . . . . . . . . . <br>
 * . . . . . # # # # # # # # # # # # # # # # # # . . . . . . . . . . . . . . . . . . . . . . . . . . . <br>
 * . . . . . # # # # # # # # # # # # # # # # # # . . . . . . . . . . . . . . . . . . . . . . . . . . . <br>
 * . . . . . # # # # # # # # # # # # # # # # # # # . . . . . . . . . . . . . . . . . . . . . . . . . . <br>
 * . . . . . . . # # # # # # # # # # # # # # # # # # . . . . . . . . . . . . . . . . . . . . . . . . . <br>
 * . . . . . . # # # # # # # # # # # # # # # # # # # # . . . . . . . . . . . . . . . . . . . . . . . . <br>
 * . . . . . # # # # # # # # # # # # # # # # # # # # # . . . . . . . . . . . . . . . . . . . . . . . . <br>
 * . . . . # # # # # # # # # # # # # # # # # # # # # # # . . . . . . . . . . . . . . . . . . . . . . . <br>
 * . . . . # # # # # # # # # # # # # # # # # # # # # # # # . . . . . . . . . . . . . . . . . . . . . . <br>
 * . . . . # # # # # # # # # # # # # # # # # # # # # # # # # . . . . . . . . . . . . . . . . . . . . . <br>
 * . . . . . # # # # # # # # # # # # # # # # # # # # # # # # # . . . . . . . . . . . . . . . . . . . . <br>
 * . . . . # # # # # # # # # # # # # # # # # # # # # # # # # # . . . . . . . . . . . . . . . . . . . . <br>
 * # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # . . . . . . . . . . . . . . . . . . . . <br>
 * # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # . . . . . . . . . . . # # . . . . . . <br>
 * # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # . . . . . . . . . # # # # . . . . . . <br>
 * # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # . . . . . . . # # # # # . . . . . . <br>
 * # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # . . . . . . . # # # # . . . . . . <br>
 * # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # . . . . . . # # # # # # . . . . . <br>
 * # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # . . . . . . . . # # # # # . . . . <br>
 * # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # . . . . . . # # # # # # # . . <br>
 * # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # . . . . . . # # # # # # # . . <br>
 * # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # . . . # # # # # # # # # # . . <br>
 * # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # . . # # # # # # # . . . . . . <br>
 * # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # . . . . . . <br>
 * # # # # # # # # # # # # # # # # # # # # # # # . . # # # # # # # # # # # # # # # # # # . . . . . . . <br>
 * # # # # # # # # # # # # # # # # # # # # # # # . . # # # # # # . # # # # # # # # # # . . . . . . . . <br>
 * # # # # # # # # # # # # # # # # # # # # # # # # . # # # # # # # # # # # # # # # . . . . . . . . . . <br>
 * # # # # # # # # # # # # # # # # # # # # # # # # . # # # # # # # # # # # # # # # . . . . . . . . . . <br>
 * # # # # # # # # # # # # # # # # # # # # # # # # . # # # # # # # # # # # # # # # . . . . . . . . . . <br>
 * . # # # # # # # # # # # # # # # # # # # # # # # . # # # # # # # # # # # # . . . . . . . . . . . . . <br>
 * # # # # # # # # # # # # # # # # # # # # # # # # . . . # # . # # # # # . . . . . . . . . . . . . . . <br>
 * # # # # # # # # # # # # # # # # # # # # # # # # . . . . . . . . . . . . . . . . . . . . . . . . . . <br>
 * # # # # # # # # # # # # # # # # # # # # # # # . . . . . . . . . . . . . . . . . . . . . . . . . . . <br>
 * # # # # # # # # # # # # # # # # # # # # # # . . . . . . . . . . . . . . . . . . . . . . . . . . . . <br>
 * # # # # # # # # # # # # # # # # # # # # # # . . . . . . . . . . . . . . . . . . . . . . . . . . . . <br>
 * # # # # # # # # # # # # # # # # # # # # # # . . . . . . . . . . . . . . . . . . . . . . . . . . . . <br>
 * # # # # # # # # # # # # # # # # # # # # # # # # # # # . . . . . . . . . . . . . . . . . . . . . . . <br>
 * # # # # # # # # # # # # # # # # # # # # # # # # # # # . . . . . . . . . . . . . . . . . . . . . . . <br>
 * # # # # # # # # # # # # # # # # # # # # # # # # # # # . . . . . . . . . . . . . . . . . . . . . . . <br>
 * # # # # # # # # # # # # # # # # # # # # # . # # # # # . . . . . . . . . . . . . . . . . . . . . . . <br>
 * # # # # # # # # # # # # # # # # # # . . . . # # # # # . . . . . . . . . . . . . . . . . . . . . . . <br>
 * # # # # # # # # # # # # # # # # # # . . . . # # # # . . . . . . . . . . . . . . . . . . . . . . . . <br>
 * # # # # # # # # # # # # # # # # # . . . . . # # # # . . . . . . . . . . . . . . . . . . . . . . . . <br>
 * # # # # # # # # # # # # . # # # . . . . . . . # # . . . . . . . . . . . . . . . . . . . . . . . . . <br>
 * # # # # # # # # # # # # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <br>
 * # # # # # # # # # # # # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <br>
 * # . . . # # # . # # # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .<br>
 */
